/****************************************************************************
**
** This file is part of qPhotoTag, a photo keywording application
**
** Copyright (C) 2009 Marcell Lengyel <miketkf@gmail.com>
**
** GNU General Public License
** This program is free software; you can redistribute it and/or
** modify it under the terms of the GNU General Public License
** as published by the Free Software Foundation; either version 2
** of the License, or (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
**
****************************************************************************/

#include <QtGui>
#include "mainwindowimpl.h"
//
MainWindowImpl::MainWindowImpl() 
{
	this->resize(800,600);
	createActions();
        createMenus();
	createToolBars();
	createStatusBar();
	createLayout();
	setUnifiedTitleAndToolBarOnMac(true);
        read_settings();
        setWindowTitle(tr("qPhotoTag"));
}

MainWindowImpl::~MainWindowImpl()
{
    save_settings();
}

void MainWindowImpl::createMenus()
{
    fileMenu = menuBar()->addMenu(tr("&File"));
    fileMenu->addAction(openAct);
    fileMenu->addAction(saveAct);
    fileMenu->addAction(geotagAct);
    fileMenu->addAction(exitAct);

    helpMenu = menuBar()->addMenu(tr("&Help"));
    helpMenu->addAction(aboutAct);
}

void MainWindowImpl::read_settings()
{
    QSettings settings;
    QPoint pos = settings.value("pos", QPoint(200, 200)).toPoint();
    QSize size = settings.value("size", QSize(800, 600)).toSize();
    resize(size);
    move(pos);
}

void MainWindowImpl::save_settings()
{
    /* Save postion/size of main window */
    QSettings settings;
    settings.setValue("pos", pos());
    settings.setValue("size", size());
}

void MainWindowImpl::createActions()
{
	openAct = new QAction(QIcon(":/icons/open.svg"), tr("&Open..."), this);
	openAct->setShortcuts(QKeySequence::Open);
	openAct->setStatusTip(tr("Open photos"));
	connect(openAct, SIGNAL(triggered()), this, SLOT(open()));

	saveAct = new QAction(QIcon(":/icons/save.svg"), tr("&Save..."), this);
	saveAct->setShortcuts(QKeySequence::Save);
	saveAct->setStatusTip(tr("Save the modified EXIF/IPTC info"));
	connect(saveAct, SIGNAL(triggered()), this, SLOT(save()));

	geotagAct = new QAction(QIcon(":/icons/globe.png"), tr("&Geotag"), this);
	geotagAct->setShortcut(tr("Ctrl+G"));
	geotagAct->setStatusTip(tr("Geotag the selected pictures"));
	connect(geotagAct, SIGNAL(triggered()), this, SLOT(geotag()));
	
	exitAct = new QAction(QIcon(":/icons/quit.svg"), tr("E&xit"), this);
	exitAct->setShortcut(tr("Ctrl+Q"));
	exitAct->setStatusTip(tr("Exit the application"));
	connect(exitAct, SIGNAL(triggered()), this, SLOT(close()));

        aboutAct = new QAction(tr("&About"), this);
        aboutAct->setStatusTip(tr("About qPhotoTag"));
        connect(aboutAct, SIGNAL(triggered()), this, SLOT(about()));

        saveAct->setEnabled(false);
        geotagAct->setEnabled(false);
}

void MainWindowImpl::createToolBars()
{
	toolBar = addToolBar(tr("File"));
	toolBar->addAction(openAct);
	toolBar->addAction(saveAct);
	toolBar->addAction(geotagAct);
	toolBar->addAction(exitAct);
}

void MainWindowImpl::createStatusBar()
{
	statusBar()->showMessage(tr("Ready"));
}

void MainWindowImpl::createLayout()
{

        captionGroup = new QGroupBox(tr("Caption"), this);
        caption_entry = new CaptionEdit(this);
        captionGroupLayout = new QVBoxLayout(captionGroup);
        captionGroupLayout->addWidget(caption_entry);
	captionGroup->setMaximumHeight(100);
	
        tagListGroup = new QGroupBox(tr("Tags for selected photos"), this);
        tag_list = new TagList(this);
	QVBoxLayout *tagListGroupLayout = new QVBoxLayout(tagListGroup);
	tagListGroupLayout->addWidget(tag_list);

	
        add_tag_entry = new QLineEdit(this);
	// IPTC keyword max length is 64
	add_tag_entry->setMaxLength(64);
        add_tag_button = new QPushButton(tr("Add tag"), this);
        QWidget *add_tag_frame = new QWidget(this);
	QHBoxLayout *add_tag_layout = new QHBoxLayout(add_tag_frame);
	add_tag_layout->addWidget(add_tag_entry);
	add_tag_layout->addWidget(add_tag_button);

        tagPoolGroup = new QGroupBox(tr("Tag pool"), this);
        tag_pool = new TagList(this);
	QVBoxLayout *tagPoolGroupLayout = new QVBoxLayout(tagPoolGroup);
	tagPoolGroupLayout->addWidget(tag_pool);

        add_button = new QPushButton(tr("Add selected"), this);
        remove_button = new QPushButton(tr("Remove selected"), this);
        QWidget *add_remove_frame = new QWidget(this);
	QHBoxLayout *add_remove_layout = new QHBoxLayout(add_remove_frame);
	add_remove_layout->addWidget(add_button);
	add_remove_layout->addWidget(remove_button);
		
        QWidget *frameEntries = new QWidget(this);
	frameEntries->setMaximumWidth(300);
	QVBoxLayout *entryLayout = new QVBoxLayout(frameEntries);
	entryLayout->addWidget(captionGroup);
	entryLayout->addWidget(tagListGroup);
	entryLayout->addWidget(add_tag_frame);
	entryLayout->addWidget(tagPoolGroup);
	entryLayout->addWidget(add_remove_frame);
	
        photoview = new PhotoView(this);
	connect(photoview->selectionModel(), 
			SIGNAL(selectionChanged(const QItemSelection &, const QItemSelection &)),
			this, 
			SLOT(on_photoview_selection_changed(const QItemSelection &, const QItemSelection &)));
        connect(photoview,
                        SIGNAL(doubleClicked(const QModelIndex &)),
                        this,
                        SLOT(on_photoview_doubleclick(const QModelIndex &)));
        connect(add_tag_button,
			SIGNAL(clicked()),
			this,
			SLOT(on_add_tag_clicked()));
	connect(add_tag_entry,
			SIGNAL(returnPressed()),
			this,
			SLOT(on_add_tag_clicked()));
	connect(add_button,
			SIGNAL(clicked()),
			this,
			SLOT(on_add_button_clicked()));
        connect(tag_pool,
                        SIGNAL(doubleClicked(const QModelIndex &)),
                        this,
                        SLOT(on_add_button_clicked()));
        connect(remove_button,
                        SIGNAL(clicked()),
                        this,
                        SLOT(on_remove_button_clicked()));
        connect(tag_list,
                        SIGNAL(tagListFocusIn()),
                        this,
                        SLOT(on_tag_list_focus_in()));
        connect(tag_pool,
                        SIGNAL(tagListFocusIn()),
                        this,
                        SLOT(on_tag_pool_focus_in()));
        connect(caption_entry,
                        SIGNAL(captionEditChanged()),
                        this,
                        SLOT(on_caption_changed()));

        caption_entry->setEnabled(false);
        add_tag_button->setEnabled(false);
        add_tag_entry->setEnabled(false);
        add_button->setEnabled(false);
        remove_button->setEnabled(false);
        tag_list->setEnabled(false);
        tag_pool->setEnabled(false);

        QWidget *centralWidget = new QWidget(this);
	QHBoxLayout *hbox = new QHBoxLayout(centralWidget);
	hbox->addWidget(frameEntries);
	hbox->addWidget(photoview);
	
	setCentralWidget(centralWidget);
}

void MainWindowImpl::on_caption_changed()
{
    if (photoview->is_selection())
    {
        photoview->add_caption_to_selected(caption_entry->toPlainText());
        saveAct->setEnabled(true);
    }
}


void MainWindowImpl::on_remove_button_clicked()
{
	if (photoview->is_selection() && tag_list->is_selection())
	{
		QStringList tags_to_remove = QStringList(tag_list->get_selected_tags());
		photoview->remove_tags_from_selected(tags_to_remove);
		// refresh the view
		on_photoview_selection_changed(QItemSelection(),QItemSelection());
	}
}

void MainWindowImpl::on_add_button_clicked()
{
	if (photoview->is_selection() && tag_pool->is_selection())
	{
		photoview->add_tags_to_selected(tag_pool->get_selected_tags());
		// merge the existing tag_list and the selected tags from the tag_pool
		QStringListModel *tlm = (QStringListModel *)tag_list->model();
		QStringList merged_list = QStringList(tlm->stringList());
		QStringList selected_tags = QStringList(tag_pool->get_selected_tags());
		for ( QStringList::iterator it = selected_tags.begin(); it != selected_tags.end(); ++it )
			if (! merged_list.contains(*it))
				merged_list.append(*it);
		tlm->setStringList(merged_list);

	}
		
}

void MainWindowImpl::on_add_tag_clicked()
{
	QString new_tag = add_tag_entry->text();
	if (! new_tag.isEmpty() 
		&& ! photoview->isEmpty() 
		&& photoview->is_selection())
		handle_add_tag(new_tag);
}

void MainWindowImpl::handle_add_tag(const QString &new_tag)
{
	tag_list->add_tag(new_tag);
	tag_pool->add_tag(new_tag);
	photoview->add_tag_to_selected(new_tag);
	add_tag_entry->clear();
        saveAct->setEnabled(true);
}

void MainWindowImpl::on_photoview_selection_changed(const QItemSelection &,
const QItemSelection &)
{
	caption_entry->clear();
	tag_list->clear();
	caption_entry->setPlainText(photoview->get_selected_caption());
	QStringListModel *tlm = (QStringListModel *)tag_list->model();
	tlm->setStringList(photoview->get_selected_tag_list());
        if (photoview->is_selection())
        {
            caption_entry->setEnabled(true);
            add_tag_button->setEnabled(true);
            add_tag_entry->setEnabled(true);
            add_button->setEnabled(true);
            remove_button->setEnabled(true);
            geotagAct->setEnabled(true);
            tag_list->setEnabled(true);
            tag_pool->setEnabled(true);
        }
        else
        {
            caption_entry->setEnabled(false);
            add_tag_button->setEnabled(false);
            add_tag_entry->setEnabled(false);
            add_button->setEnabled(false);
            remove_button->setEnabled(false);
            geotagAct->setEnabled(false);
            tag_list->setEnabled(false);
            tag_pool->setEnabled(false);
        }

}

void MainWindowImpl::save()
{
    photoview->save_exif_data();
    saveAct->setEnabled(false);
    QMessageBox::StandardButton reply;
    reply = QMessageBox::information(this, tr("IPTC Data Saved"),
                                     tr("Success! The IPTC info was updated in the photos."));
}

void MainWindowImpl::open()
{
        QSettings settings;
        QString dir = settings.value("lastUsedDir", QString("")).toString();
	QStringList fileNames = QFileDialog::getOpenFileNames(this, tr("Open Photos"), 
                                                 dir, tr("Image Files (*.jpg *.JPG)"));
	if (! fileNames.isEmpty())
	{
		QStringList list = fileNames;
		QStringList::Iterator it = list.begin();
                settings.setValue("lastUsedDir", QFileInfo(*it).absolutePath());
		while( it != list.end() ) 
		{
			photoview->new_file( *it);
			statusBar()->showMessage(tr("Opening file: %1").arg(*it));
			++it;
		}
		QStringListModel *tpm = (QStringListModel *)tag_pool->model();
		tpm->setStringList(photoview->get_tag_list());
        }
	statusBar()->showMessage(tr("Ready"));
}

void MainWindowImpl::on_tag_list_focus_in()
{
    tag_pool->clearSelection();
}

void MainWindowImpl::on_tag_pool_focus_in()
{
    tag_list->clearSelection();
}

void MainWindowImpl::on_photoview_delete_pressed()
{
    // refresh
    on_photoview_selection_changed(QItemSelection(), QItemSelection());
    if (photoview->isEmpty())
    {
        caption_entry->setEnabled(false);
        add_tag_button->setEnabled(false);
        add_tag_entry->setEnabled(false);
        add_button->setEnabled(false);
        remove_button->setEnabled(false);
        saveAct->setEnabled(false);
        geotagAct->setEnabled(false);
        tag_list->setEnabled(false);
        tag_pool->setEnabled(false);

    }
}

void MainWindowImpl::on_photoview_doubleclick(const QModelIndex &index)
{
    qDebug("pw doublecleck");
    photoview->display_picture_dialog(index);
}

void MainWindowImpl::about()
{
    QMessageBox::about(this, tr("About qPhotoTag"),
             tr("<center><h2>qPhotoTag %1</h2></center>"
        "qPhotoTag is inspired by <a href=\"http://www.itagsoftware.com\">iTag</a> that is why the UI "
        "is similar to the UI of iTag. The primary usecase for qPhotoTag is to add keywords, "
        "captions and GPS coordinates to digital camera photos in a way that is "
        "understood by Picasa.<br>"
        "<br>"
        "With qPhotoTag currently it is possible to add IPTC keywords and caption, add "
        "GPS coordinates from a waypoints.gpx file to both EXIF header and IPTC keywords. "
        "It has not been extensively tested, so make sure to back up your photos before "
        "running qPhotoTag on them.<br>"
        "<br>"
        "Copyright (c) 2009, Marcell Lengyel <miketkf@gmail.com><br>"
        "<br>"
        "You may modify and redistribute the program under the terms of the GPL (version 2 or later).<br>"
        "We provide no warranty for this program."
        ).arg(QTAG_VERSION));
}
